package com.hlxj.license.client;

import com.hlxj.license.client.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @功能:【ScheduleCheck 】
 * @作者:代守诚
 * @日期:2019/5/20
 * @时间:14:18
 */
@Component
public class LicenseCheck {

    @Value("${licenseTime.webUrl}")
    private String webUrl;
    @Value("${licenseServer.checkUrl}")
    private String checkUrl;
    @Value("${sslContext.keyStorePath}")
    private String keyStorePath;
    @Value("${sslContext.keyStorepass}")
    private String keyStorepass;

    //需要一个接口来决定是否开启软件
    public boolean checkLisence() {
        Map<String, String> infoMap = decodeData();
        if (!verifyMachine(infoMap)) {
            return false;
        }

        String endTime = infoMap.get("endTime");

        String netWorkTime = DateUtil.getNetWorkTime(webUrl);
        if (StringUtils.isEmpty(netWorkTime)) {
            netWorkTime = DateUtil.getCurrentTime();
        }

        Long endTimeL = DateUtil.getTime(endTime);
        Long netWorkTimeL = DateUtil.getTime(netWorkTime);

        if ((endTimeL - netWorkTimeL) <= 0) {
            return false;
        }

        return true;
    }

    public boolean checkLisenceByNet() {
        Map<String, String> infoMap = decodeData();
        if (!verifyMachine(infoMap)) {
            return false;
        }
        StringBuilder strBuilder = new StringBuilder();
        strBuilder.append("UUID").append("=").append(infoMap.get("UUID")).append(";");
        strBuilder.append("CPU").append("=").append(infoMap.get("CPU")).append(";").append("Mainboard").append("=").append(infoMap.get("Mainboard")).append(";");
        strBuilder.append("MAC").append("=").append(infoMap.get("MAC")).append(";").append("endTime").append("=").append(infoMap.get("endTime"));

        String publicKey = FileUtil.readFileContent("publicKey");
        byte[] data = strBuilder.toString().getBytes();
        byte[] encodedData = null;
        try {
            encodedData = RSAUtil.encryptByPublicKey(data, publicKey);

        } catch (Exception e) {
            e.printStackTrace();
        }
        //调用服务端验证返回结果
        String response = null;
        try {
//            SSLContext sSLContext = HttpClientTool.getSSLContext(keyStorePath, keyStorepass);
            String encode = StringUtil.bytesToString(encodedData);
            System.out.println("加密后数据：" + encode);
            response = HttpClientTool.postJson(null, checkUrl, encode);
        } catch (Exception e) {
            e.printStackTrace();
        }

        boolean flag = Boolean.parseBoolean(response);
        return flag;
    }

    private boolean verifyMachine(Map<String, String> infoMap) {
        String cpuid = SerialNumberUtil.getCPUSerial().toUpperCase().replace(" ", "");
        String mainboard = SerialNumberUtil.getMotherboardSN().toUpperCase().replace(" ", "");
        String mac = SerialNumberUtil.getMac().toUpperCase().replace(" ", "");

        if (cpuid.equals(infoMap.get("CPU")) && mainboard.equals(infoMap.get("Mainboard")) && mac.equals(infoMap.get("MAC"))) {
            return true;
        }

        return false;
    }

    private Map<String, String> decodeData() {
        String encodeData = FileUtil.readFileContent("computerInfo");
        String publicKey = FileUtil.readFileContent("publicKey");
        Map<String, String> infoData = new HashMap<>();
        try {
            System.out.println(encodeData);
            byte[] data = StringUtil.stringToBytes(encodeData);
            byte[] decodedData = RSAUtil.decryptByPublicKey(data, publicKey);
            String target = new String(decodedData);
            System.out.println("解密后: \r\n" + target);
            String[] info = target.split(";");
            Arrays.asList(info).forEach(str ->{
                String[] computer = str.split("=");
                infoData.put(computer[0], computer[1]);
            });
            return infoData;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
